package com.yanyu.space.common.cloud.feign;

import com.yanyu.space.common.core.annotation.FeignMapping;
import com.yanyu.space.common.core.constants.SpaceConstants;
import feign.Logger;
import feign.codec.ErrorDecoder;
import okhttp3.ConnectionPool;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;

import java.util.concurrent.TimeUnit;

/**
 * @author yanyu
 */
@Configuration
@ComponentScan(basePackages = SpaceConstants.CorePackage.SPACE_FEIGN,
        useDefaultFilters = false,
        includeFilters = {
                @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = FallbackFactory.class),
                @ComponentScan.Filter(type = FilterType.ANNOTATION, value = FeignMapping.class)
        })
@EnableFeignClients(value = SpaceConstants.CorePackage.SPACE_FEIGN)
public class FeignAutoConfig {


    /**
     * 拦截器，设置请求头
     *
     * @return
     */
    @Bean
    public FeignRequestInterceptor feignRequestInterceptor() {
        return new FeignRequestInterceptor();
    }

    /**
     * 异常统一处理类
     *
     * @return
     */
    @Bean
    @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
    @ConditionalOnClass(name = "org.springframework.retry.support.RetryTemplate")
    public FeignGlobalExceptionHandler feignGlobalExceptionHandler() {
        return new FeignGlobalExceptionHandler();
    }

    /**
     * okfeign
     *
     * @return
     */
    @Bean
    @ConditionalOnProperty("feign.okhttp.enabled")
    public okhttp3.OkHttpClient okHttpClient() {
        return new okhttp3.OkHttpClient.Builder()
                //设置连接超时，不起作用，feign的优先级比较大,具体看OKHttpClient.execute方法
                .connectTimeout(10, TimeUnit.SECONDS)
                //设置读超时
                .readTimeout(10, TimeUnit.SECONDS)
                //设置写超时
                .writeTimeout(10, TimeUnit.SECONDS)
                //是否自动重连
                .retryOnConnectionFailure(true)
                .connectionPool(new ConnectionPool(30, 5L, TimeUnit.MINUTES))
                .build();
    }

    @Bean
    public ErrorDecoder feignErrorDecoder() {
        return new FeignErrorDecoder();
    }

    @Bean
    public Logger fiengCustomLogger() {
        return new FeignCustomLogger();
    }
}
